
// === uuURL ===
// depend: none
/*
uuURL.abs(url, curtdir) - return absolute URL
uuURL.dir(abspath) - return absolute directory
uuURL.parse(url) - return { url, scheme, domain, port, base, path,
                            dir, file, query, hash, fragment }
uuURL.build(url) - return "scheme://domain:port/path?query#fragment"
uuURL.parseQuery(query) - return { key: value, ... }
uuURL.buildQuery(query) - return "key=value&key=value..."
 */
(function() {
var _url; // inner namespace

_url = {
  // uuURL.abs - convert relative URL to absolute URL
  abs: function(url,       // @param URLString: rel/abs URL
                curtdir) { // @param URLString(= ""): current dir
                           // @return URLString: absolute URL
    if (!/^(file|https|http)\:\/\//.test(url)) {
      var div = document.createElement("div");
      div.innerHTML = '<a href="' + (curtdir || "") + url + '" />';
      url = div.firstChild ? div.firstChild.href
                           : /href\="([^"]+)"/.exec(div.innerHTML)[1];
    }
    return url;
  },

  // uuURL.dir - absolute path to absolute directory(chop filename)
  dir: function(abspath) { // @param PathString: absolute path
                           // @return PathString: absolute directory
    var ary = abspath.split("/");
    ary.pop();
    return ary.join("/") + "/";
  },

  // uuURL.parse - parse URL
  //    uuURL.parse(".") is current url
  parse: function(url) { // @param URLString:
                         // @return false/Hash:
                         //           { url, scheme, domain, port, base, path,
                         //             dir, file, query, hash, fragment }
    url = uuURL.abs(url);
    var dir, file, ary, hash, m;

    // file:///localhost/dir/file.ext
    m = /^file:\/\/(?:\/)?(?:localhost\/)?((?:[a-z]\:)?.*)$/.exec(url);
    if (m) {
      ary  = m[1].split("/");
      file = ary.pop();
      dir  = ary.join("/");
      return {
        url:    url,
        scheme: "file",
        domain: "",
        port:   "",
        base:   "file:///" + dir || "/", path: m[1],
        dir:    dir || "/",
        file:   file || "",
        query:  "",
        hash:   {},
        fragment: ""
      };
    }

    // http://wwww.example.com:8080/dir/file.ext?key1=value1&key2=value2#frag
    m = /^([a-z][a-z\d\+\-\.]*)\:\/\/([^\/\:]+)(?:\:(\d*))?([^\?#\s]*)(?:\?([^#]*))?(?:#(.*))?/i.exec(url);
    if (m) {
      if (m[4]) { // path
        ary  = m[4].split("/");
        file = ary.pop();
        dir  = ary.join("/");
      }
      hash = m[5] ? uuURL.parseQuery(m[5]) : {};
      return {
        url:    url,          // AbsoluteURLString( "http://..." )
        scheme: m[1],         // SchemeString( "file" or "http" or "https" )
        domain: m[2],         // DomainNameString( "www.example.com" )
        port:   m[3] || "",   // PortNumber( "8080" or "" ) - not Number
        base:   (m[1] + "://" + m[2]) + (m[3] ? ":" + m[3] : "") + (dir || "/"),
        path:   m[4] || "/",  // PathString( "/dir/file.ext" or "/" )
        dir:    dir  || "/",  // DirString( "/dir" or "/" )
        file:   file || "",   // FileNameString( "file.ext" or "" )
        query:  m[5] || "",   // QueryString( "key1=value1&key2=value2" or "" )
        hash:   hash,         // QueryHash( { key1: "value1", key2: "value2" } )
        fragment: m[6] || ""  // FragmentString( "menu1" or "" )
      };
    }
    return false;
  },

  // uuURL.build - build URL
  build: function(url) { // @param Hash:
                         // @return String:
                         //         "scheme://domain:port/path?query#fragment"
    return [
      url.scheme, "://",
      url.domain,
      url.port ? ":" + url.port : "",
      url.path || "/",
      url.query ? "?" + url.query : "",
      url.fragment ? "#" + url.fragment : ""
    ].join("");
  },

  // uuURL.parseQuery - parse QueryString
  parseQuery: function(query) { // @param QueryString:
                                // @return Hash: { key: value, ... }
    var rv = {}, fn = decodeURIComponent;

    query.replace(/^.*\?/, "").
          replace(/&amp;/g, "&").
          replace(/(?:([^\=]+)\=([^\&]+)&?)/g, function(m, key, value) {
      return rv[fn(key)] = fn(value);
    });
    return rv;
  },

  // uuURL.buildQuery - build QueryString
  buildQuery:
      function(query) { // @param Hash:
                        // @return QueryString: "key=value&key=value..."
    var rv = [], fn = encodeURIComponent, i;

    for (i in query) {
      rv.push(fn(i) + "=" + fn(query[i]));
    }
    return rv.join("&");
  }
};

// --- initialize ---

// --- export ---
window.uuURL = _url; // window.uuURL
})(); // uuURL scope

